package com.weir.quarkus.base.system.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;

import com.weir.quarkus.base.system.entity.SysModule;
import com.weir.quarkus.base.system.repository.SysModuleRepository;
import com.weir.quarkus.base.system.vo.MenuVo;
import com.weir.quarkus.base.system.vo.VueMenuMetaVo;
import com.weir.quarkus.base.system.vo.VueMenuVo;
import com.weir.quarkus.base.system.vo.VueTreeVo;


@ApplicationScoped
public class SysModuleService {

	@Inject
	SysModuleRepository sysModuleRepository;
	
	@Transactional
	public void del(Integer id) {
		List<SysModule> list = SysModule.list("parentId = ?1", id);
		for (SysModule sysModule : list) {
			SysModule.deleteById(sysModule.id);
			del(sysModule.id);
		}
		SysModule.deleteById(id);
	}

	public List<VueMenuVo> treeVue(Integer id) {
		List<SysModule> tmenus = null;
		if (id == null) {
			tmenus = sysModuleRepository.list("parentId is null and stepType = 1");
		} else {
			tmenus = sysModuleRepository.list("parentId = ?1 and stepType = 1", id);
		}
		List<VueMenuVo> menus = new ArrayList<VueMenuVo>();
		for (SysModule tmenu : tmenus) {
			VueMenuVo m = new VueMenuVo();
			m.id=tmenu.id;
			m.path = tmenu.path;
			m.name = tmenu.code;
			m.component = tmenu.component;
			m.meta = new VueMenuMetaVo(tmenu.name);
//			m.redirect = "/dashboard/console";
			menus.add(m);
		}
		for (VueMenuVo vueMenuVo : menus) {
			getchilds(vueMenuVo);
		}
		return menus;
	}
	
	private void getchilds(VueMenuVo vueMenuVo) {
		List<SysModule> tmenus = sysModuleRepository.list("stepType = 1 and parentId = ?1", vueMenuVo.id);
		if (tmenus != null && !tmenus.isEmpty()) {
			for (SysModule tmenu : tmenus) {
				VueMenuVo m = new VueMenuVo();
				m.path = tmenu.path;
				m.name = tmenu.code;
				m.component = tmenu.component;
				m.meta = new VueMenuMetaVo(tmenu.name);
				vueMenuVo.children.add(m);
				getchilds(m);
			}
		}
	}
	
	public List<MenuVo> tree(Integer id) {
		List<SysModule> tmenus = null;
		if (id == null) {
			tmenus = sysModuleRepository.list("parentId is null");
		} else {
			tmenus = sysModuleRepository.list("parentId = ?1", id);
		}
		List<MenuVo> menus = new ArrayList<MenuVo>();
		MenuVo m = null;
		for (SysModule tmenu : tmenus) {
			m = new MenuVo();
			m.id = tmenu.id;
			m.text = tmenu.name;
			m.name = tmenu.name;
			m.code = tmenu.code;
			m.url = tmenu.url;
			m.parentId = tmenu.parentId != null ? tmenu.parentId : null;
			List<SysModule> tmenus2 = sysModuleRepository.list("parentId = ?1", tmenu.id);
			Map<String, Object> attributes = new HashMap<String, Object>();
			attributes.put("url", tmenu.url);
			m.attributes = attributes;
			if (tmenus2 != null && !tmenus2.isEmpty()) {
				m.state = "closed";
			} else {
				m.state = "open";
			}
			menus.add(m);
		}
		return menus;
	}
	
	public List<MenuVo> allTree() {
		List<SysModule> tmenus = SysModule.findAll().list();
		List<MenuVo> menus = new ArrayList<MenuVo>();
		MenuVo m = null;
		for (SysModule tmenu : tmenus) {
			m = new MenuVo();
			m.id = tmenu.id;
			m.name = tmenu.name;
			m.url = tmenu.url;
			m.text = tmenu.name;
			m.code = tmenu.code;
			if (tmenu.parentId != null) {
				SysModule t = SysModule.findById(tmenu.parentId);
				if (t != null) {
					m.parentId = t.id;
					m.parentName = t.name;
				}
			}
			menus.add(m);
		}
		return menus;
	}
	
	public List<VueTreeVo> allUserTreeVue(Integer userId) {
		List<SysModule> modules = SysModule
				.find("select m from SysModule m inner join SysRoleModule rm on m.id = rm.moduleId "
						+ "INNER JOIN SysUserRole ur on rm.roleId=ur.roleId where ur.userId = ?1", userId)
				.list();
		return menuToTree(modules);
	}
	
	public List<VueTreeVo> allTreeVue() {
		List<SysModule> tmenus = SysModule.findAll().list();
		return menuToTree(tmenus);
	}
	
	private List<VueTreeVo> menuToTree(List<SysModule> tmenus) {
		List<VueTreeVo> menus = new ArrayList<>();
		VueTreeVo m = null;
		for (SysModule tmenu : tmenus) {
			if (tmenu.parentId == null) {				
				m = new VueTreeVo();
				m.id = tmenu.id;
				m.label = tmenu.name;
				m.key = tmenu.code;
				m.subtitle = tmenu.code;
				m.auth = tmenu.code;
				m.path = tmenu.path;
				m.component = tmenu.component;
				m.icon = tmenu.icon;
				m.enable = tmenu.enable;
				m.stepType = tmenu.stepType;
				m.createTime = tmenu.createTime;
				menus.add(m);
			}
		}
		for (VueTreeVo vueTreeVo : menus) {
			getchildTree(vueTreeVo, tmenus);
		}
		return menus;
	}
	
	private void getchildTree(VueTreeVo vueTreeVo, List<SysModule> tmenus) {
		for (SysModule tmenu : tmenus) {
			if (vueTreeVo.id.equals(tmenu.parentId)) {
				VueTreeVo m = new VueTreeVo();
				m.id = tmenu.id;
				m.label = tmenu.name;
				m.key = tmenu.code;
				m.subtitle = tmenu.code;
				m.auth = tmenu.code;
				m.path = tmenu.path;
				m.parentPath = vueTreeVo.path;
				m.component = tmenu.component;
				m.icon = tmenu.icon;
				m.enable = tmenu.enable;
				m.stepType = tmenu.stepType;
				m.createTime = tmenu.createTime;
				if (vueTreeVo.children == null){
					vueTreeVo.children = new ArrayList<>();
				}
				vueTreeVo.children.add(m);
				getchildTree(m, tmenus);
			}
		}
		
	}
}
